<template>
  <div class="">
    <div v-for="(tag, index) in tags" :key="index" class="mb-1 flex items-center">
      <input v-model="tags[index]" @change="updateTag()" class="border p-2 w-full" />
      <button @click="deleteTag(index)" class="ml-2 p-2 border text-white rounded">❌</button>
    </div>
    <div class="mt-4 flex items-center">
      <input v-model="newTag" @keyup.enter="addTag" placeholder="新增标签" class="border p-2 w-full border-green-500" />
      <button @click="addTag" class="text-lg ml-2 p-1 bg-green-500 text-white rounded">✅</button>
    </div>
    <!-- 功能按钮区 -->
    <div class="mt-4">
      <div v-if="missingDataMessage.length">
        <p v-for="msg in missingDataMessage" class="text-red-500 mb-4">{{ msg }}</p>
      </div>
      <button @click="suggestTags" class="p-2 bg-blue-500 fontb text-white rounded">
        <svg v-show="isSuggesting" class="inline animate-spin h-4 w-4 mr-3 text-white"
          xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
          <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
          <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
        </svg>
        <span v-show="!isSuggesting">
          猜测标签
        </span>
      </button>
      <!-- 开始分组按钮 -->
      <button @click="startGrouping" class="p-2 ml-3 bg-green-600 text-white rounded">
        <svg v-show="isGrouping" class="inline animate-spin h-4 w-4 mr-3 text-white" xmlns="http://www.w3.org/2000/svg"
          fill="none" viewBox="0 0 24 24">
          <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
          <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
        </svg>
        <span v-show="!isGrouping">
          开始分组
        </span>
      </button>
    </div>
    <!-- 危险按钮区 -->
    <div class="mt-4">
      <!-- 清空标签按钮 -->
      <button @click="clearTags" class="p-2 bg-red-400 text-white rounded">清空标签</button>
      <!-- 取消分组按钮 -->
      <button @click="cancelGrouping" class="p-2 ml-3 bg-red-400 text-white rounded">
        取消分组
      </button>
    </div>

  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { setStorage, getStorage } from '../utils/storage';
import { generateGroupPrompt, suggestTagsPrompt } from '../utils/prompts';
import { sendRequestToLLM } from '../utils/llmService';
import { extractTags } from '../utils';
import { fixAndParseJSON } from '../utils/jsonRepair';

const tags = ref([]);
const newTag = ref('');
const isSuggesting = ref(false);
const isGrouping = ref(false);

const missingDataMessage = ref([]);

onMounted(async () => {
  let tagsData = await getStorage('tags');
  tagsData = tagsData ? JSON.parse(tagsData) : [];
  await saveTags()
});

const checkMissingData = async () => {
  missingDataMessage.value = [];

  let tagsData = await getStorage('tags');
  tagsData = tagsData ? JSON.parse(tagsData) : [];

  const modelSelectedData = await getStorage('modelSelected');
  const ollamaAddressData = await getStorage('ollamaAddress');
  console.log(tagsData, modelSelectedData, ollamaAddressData);
  
  if (!tagsData.length) {
    missingDataMessage.value.push('缺少标签数据，请添加标签。');
  } 
  if (!modelSelectedData) {
    missingDataMessage.value.push('缺少模型选择数据，请选择模型。');
  } 
  if (!ollamaAddressData) {
    missingDataMessage.value.push('缺少 Ollama 地址数据，请配置地址。');
  }
};

const saveTags = async () => {
  await setStorage('tags', JSON.stringify(tags.value));
  await checkMissingData()
};

const updateTag = () => {
  saveTags();
};

const addTag = async () => {
  if (newTag.value.trim()) {
    tags.value.push(newTag.value.trim());
    newTag.value = '';
    await saveTags();
  }
};

const deleteTag = async (index) => {
  tags.value.splice(index, 1);
  await saveTags();
};

const clearTags = async () => {
  tags.value = [];
  await saveTags();
};

const generateTitle = (item) => {
  const url = new URL(item.url);
  const domainParts = url.hostname.split('.');
  const domain = domainParts.slice(-2).join('.');
  const title = item.title.length > 30 ? item.title.slice(0, 30) : item.title;
  return `${domain}-${title}`;
}
const generateTitleList = (items) => {
  return items.map(item => {
    return generateTitle(item);
  });
}

const suggestTags = async () => {
  isSuggesting.value = true;

  const res = await chrome.tabs.query({currentWindow: true});
  console.log(res[3]);
  
  const titleList = generateTitleList(res);

  const prompt = JSON.stringify({
    titles: titleList
  })

  try {
    // ollama generate completion 配置对象
    const config = {
      model: await getStorage('modelSelected'),
      system: suggestTagsPrompt,
      prompt,
      format: 'json',
      stream: false,
    };
    const res = await sendRequestToLLM('/api/generate', config);
    const newTags = extractTags(JSON.parse(res.response))
    // 将 newTags 添加到 tags 数组中，去重.
    tags.value = [...new Set([...tags.value, ...newTags])];
    // 如果整个数组都没有'其他'这个分类，则加上
    if (!tags.value.includes('其他')) {
      tags.value.push('其他');
    }
    await saveTags();
  } catch (error) {
    console.error('Error sending request to LLM:', error);
  } finally {
    isSuggesting.value = false;
  }
};

const startGrouping = async () => {
  // 如果 tags 是空的就返回并 console.error
  if (tags.value.length === 0) {
    console.error('Tags array is empty. Cannot group tabs.');
    return;
  }

  isGrouping.value = true;

  const tabs = await chrome.tabs.query({currentWindow: true});

  const tabInfoList = tabs.map((tab) => {
    return {
      id: tab.id,
      title: tab.title,
      url: tab.url,
    };
  });

  const result = tags.value.map((tag) => {
    return {
      tag,
      tabIds: [],
    };
  });

  // const titleList = generateTitleList(res);
  // tabInfoList.length = 1
  try {
    await Promise.all(
      tabInfoList.map(async (tab) => {
        if (!tab.url) return;
        const config = {
          model: await getStorage('modelSelected'),
          system: await generateGroupPrompt(),
          prompt: `网页标题是: ${generateTitle(tab)}`,
          stream: false,
        };
        const res = await sendRequestToLLM('/api/generate', config);
        const tag = res.response;
        
        let index = tags.value.indexOf(tag);
        if (index === -1) {
          index = tags.value.indexOf('其他');
        };
        if (index === -1) return;
        
        result[index].tabIds.push(tab.id);
      })
    );
    console.log(result);
    
    saveTabGroups(result);
  } catch (error) {
    console.error(error);
  } finally {
    isGrouping.value = false;
  }
};

const saveTabGroups = async (tabGroups) => {
  let groups = await getStorage('groups');
  if(!groups) {
    groups = {};
    await setStorage('groups', groups);
  }

  // {tag: 'tag', tabIds: [1,2,3]}
  tabGroups.forEach(tabGroup => {
    const groupId = groups[tabGroup.tag]
    console.log(tabGroup);
    if(tabGroup.tabIds.length === 0) return
    chrome.tabs.group({tabIds: tabGroup.tabIds, groupId}, newGroupId=>{
      if(!groupId) {
        chrome.tabGroups.update(newGroupId, { title: tabGroup.tag });
        groups[tabGroup.tag] = newGroupId;
        setStorage('groups', groups);
      }
    });
  });
};

const cancelGrouping = async () => {
  const tabs = await chrome.tabs.query({currentWindow: true});
  // 循环遍历所有标签，用 chrome extension 接口api取消分组
  await chrome.tabs.ungroup(tabs.map((tab) => tab.id))
  await setStorage('groups', {});
};
</script>
